﻿using System.IO;
using System.Reflection;
using System.Text.Json;

namespace DimensionsHelper.Client.Navigation;

internal class NavigationTargetSource
{
    private const string ResourceName = "DimensionsHelper.Client.Resources.NavigationTagets.json";
    
    private NavigationTargetSource()
    {
        string jsonText = ReadJsonResource();
        _navigationTargets = JsonSerializer.Deserialize<List<NavigationTargetData>>(jsonText) ?? [];
        BuildData(_navigationTargets);
    }

    public static NavigationTargetSource Instance => new();


    private readonly List<NavigationTargetData> _navigationTargets;
    private readonly List<NavigationTargetData> _keyedNavigationTargets = [];
    
    public IReadOnlyList<NavigationTargetData> NavigationTargets => _navigationTargets;
    
    public IReadOnlyList<NavigationTargetData> KeyedNavigationTargets => _keyedNavigationTargets;
    

    private static string ReadJsonResource()
    {
        Assembly assembly = typeof(NavigationTargetSource).Assembly;
        using Stream? stream = assembly.GetManifestResourceStream(ResourceName);

        if (stream == null)
        {
            return string.Empty;
        }

        using StreamReader reader = new(stream);
        return reader.ReadToEnd();
    }


    private void BuildData(List<NavigationTargetData> navigationTargets)
    {
        foreach (NavigationTargetData data in navigationTargets)
        {
            BuildData(data, null);
        }
    }


    private void BuildData(NavigationTargetData data, string? currentScope)
    {
        string scope = currentScope ?? "";

        if (!string.IsNullOrEmpty(data.Scope))
        {
            if (!string.IsNullOrEmpty(scope))
            {
                scope += ".";
            }
            
            scope += data.Scope;
        }

        if (!string.IsNullOrEmpty(data.Key) && !string.IsNullOrEmpty(scope))
        {
            data.Key = scope + "." + data.Key;
        }

        if (!string.IsNullOrEmpty(data.Key))
        {
            _keyedNavigationTargets.Add(data);
        }

        foreach (NavigationTargetData item in data.Items)
        {
            item.ParentData = data;
            BuildData(item, scope);
        }
    }
    
}